package main

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"syscall"
	"time"
	"unsafe"
)

const (
	mysqlServiceName   = "DectaskMysql8"
	redisServiceName   = "DectaskRedis"
	dectaskServiceName = "Dectask"
	SW_SHOWNORMAL      = 1
)

func main() {
	// 检查管理员权限
	if !isAdmin() {
		runAsAdmin()
		return
	}

	fmt.Println("=== Dectask 卸载程序 ===")

	// 1. 停止并删除 MySQL 服务
	if err := uninstallService(mysqlServiceName); err != nil {
		fmt.Printf("卸载 MySQL 服务失败: %v\n", err)
	} else {
		fmt.Println("MySQL 服务已卸载")
	}

	// 2. 停止并删除 Redis 服务
	if err := uninstallService(redisServiceName); err != nil {
		fmt.Printf("卸载 Redis 服务失败: %v\n", err)
	} else {
		fmt.Println("Redis 服务已卸载")
	}

	// 3. 停止 Dectask 服务
	if err := uninstallService(dectaskServiceName); err != nil {
		fmt.Printf("卸载 Dectask 服务失败: %v\n", err)
	} else {
		fmt.Println("Dectask 服务已卸载")
	}
	name := strings.ToLower(dectaskServiceName)
	cmd := exec.Command("taskkill", "/f", "/im", name+".exe")
	err := cmd.Run()
	if err != nil {
		fmt.Printf("taskkill failed: %v\n", err)
	}

	// 3. 删除可能残留的文件
	if err := removeLeftoverFiles(); err != nil {
		fmt.Printf("删除残留文件失败: %v\n", err)
	} else {
		fmt.Println("残留文件已清理")
	}

	fmt.Println("\n=== 卸载完成 ===")
}

func uninstallService(serviceName string) error {
	// 检查服务是否存在
	if !serviceExists(serviceName) {
		return nil // 服务不存在，无需处理
	}

	// 停止服务
	stopCmd := exec.Command("net", "stop", serviceName)
	stopCmd.Stdout = os.Stdout
	stopCmd.Stderr = os.Stderr
	_ = stopCmd.Run() // 忽略错误，因为服务可能已经停止

	// 删除服务
	deleteCmd := exec.Command("sc", "delete", serviceName)
	deleteCmd.Stdout = os.Stdout
	deleteCmd.Stderr = os.Stderr
	if err := deleteCmd.Run(); err != nil {
		return fmt.Errorf("删除服务失败: %v", err)
	}

	// 等待服务被删除
	time.Sleep(2 * time.Second)
	return nil
}

func removeLeftoverFiles() error {
	// 获取当前工作目录
	rootDir, err := os.Getwd()
	if err != nil {
		return fmt.Errorf("获取当前目录失败: %v", err)
	}

	// 删除密码文件
	passwordFile := filepath.Join(rootDir, "mysql-password.log")
	if _, err := os.Stat(passwordFile); err == nil {
		if err := os.Remove(passwordFile); err != nil {
			return fmt.Errorf("删除密码文件失败: %v", err)
		}
	}
	// 删除mysql数据目录
	mysqlDataDir := filepath.Join(rootDir, "mysql8.0", "data")
	if _, err := os.Stat(mysqlDataDir); err == nil {
		if err := os.RemoveAll(mysqlDataDir); err != nil {
			return fmt.Errorf("删除MySQL数据目录失败: %v", err)
		}
	}
	// 删除dectask目录下的lock文件
	dctaskDir := filepath.Join(rootDir, "dectask")
	installLockFile := filepath.Join(dctaskDir, "install.lock")
	if _, err := os.Stat(installLockFile); err == nil {
		if err := os.Remove(installLockFile); err != nil {
			return fmt.Errorf("删除安装锁文件失败: %v", err)
		}
	}

	// 这里可以添加其他需要清理的文件或目录
	// 例如: 删除临时文件、日志文件等

	return nil
}

func serviceExists(name string) bool {
	cmd := exec.Command("sc", "query", name)
	if err := cmd.Run(); err != nil {
		return false
	}
	return true
}

func isAdmin() bool {
	_, err := os.Open("\\\\.\\PHYSICALDRIVE0")
	return err == nil
}

func runAsAdmin() {
	shell32 := syscall.NewLazyDLL("shell32.dll")
	shellExecute := shell32.NewProc("ShellExecuteW")

	verb := "runas"
	exe, _ := os.Executable()
	cwd, _ := os.Getwd()

	verbPtr, _ := syscall.UTF16PtrFromString(verb)
	exePtr, _ := syscall.UTF16PtrFromString(exe)
	cwdPtr, _ := syscall.UTF16PtrFromString(cwd)

	ret, _, err := shellExecute.Call(
		uintptr(0),
		uintptr(unsafe.Pointer(verbPtr)),
		uintptr(unsafe.Pointer(exePtr)),
		uintptr(0),
		uintptr(unsafe.Pointer(cwdPtr)),
		uintptr(SW_SHOWNORMAL),
	)

	if ret <= 32 {
		fmt.Printf("无法以管理员身份运行: 错误代码 %d, %v\n", ret, err)
		os.Exit(1)
	}
	os.Exit(0)
}
